{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "new Plot(title: \"We Will Control the Title\", xLabel: \"Horizontal\", yLabel: \"Vertical\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Lines"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "// just provide lists of x's and y's\n",
    "new Plot().add(new Line(x: [0, 1, 2, 3, 4, 5], y: [0, 1, 6, 5, 2, 8]))\n",
    "\n",
    "// Groovy range works\n",
    "new Plot().add(new Line(x: (0..5), y: [0, 1, 6, 5, 2, 8]))\n",
    "\n",
    "// use '<<' left-shift to save some key strokes\n",
    "new Plot() << new Line(x: (0..5), y: [0, 1, 6, 5, 2, 8])\n",
    "\n",
    "// the constructor of class Line is overloaded to take 1 or 2 lists\n",
    "// if an Line was returned, and empty plot is automatically generated\n",
    "new Line((0..5), [0, 1, 6, 5, 2, 8])\n",
    "                        \n",
    "// if x is not provided, a default list of x values (0..5) will be used\n",
    "new Line([0, 1, 6, 5, 2, 8])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Line properties"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot = new Plot(title: \"Setting line properties\")\n",
    "def ys = [0, 1, 6, 5, 2, 8]\n",
    "def ys2 = [0, 2, 7, 6, 3, 8]\n",
    "plot << new Line(y: ys, width: 10, color: Color.red)\n",
    "plot << new Line(y: ys, width: 3, color: Color.yellow)\n",
    "plot << new Line(y: ys, width: 4, color: new Color(33, 87, 141), style: StrokeType.DASH, interpolation: 0)\n",
    "plot << new Line(y: ys2, width: 2, color: new Color(212, 57, 59), style: StrokeType.DOT)\n",
    "plot << new Line(y: [5, 0], x: [0, 5], style: StrokeType.LONGDASH)\n",
    "plot << new Line(y: [4, 0], x: [0, 5], style: StrokeType.DASHDOT)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Stems"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot = new Plot();\n",
    "def y1 = [1.5, 1, 6, 5, 2, 8]\n",
    "def cs = [Color.black, Color.red, Color.gray, Color.green, Color.blue, Color.pink]\n",
    "def ss = [StrokeType.SOLID, StrokeType.SOLID, StrokeType.DASH, StrokeType.DOT, StrokeType.DASHDOT, StrokeType.LONGDASH]\n",
    "plot << new Stems(y: y1, color: cs, style: ss, width: 5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Base of Stems"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot = new Plot(title: \"Setting the base of Stems\")\n",
    "def ys = [3, 5, 2, 3, 7]\n",
    "def y2s = [2.5, -1.0, 3.5, 2.0, 3.0]\n",
    "plot << new Stems(y: ys, width: 2, base: y2s)\n",
    "plot << new Points(y: ys)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Bars"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot = new Plot(title: \"Bars\")\n",
    "def cs = [new Color(255, 0, 0, 128)] * 5 // transparent bars\n",
    "cs[3] = Color.red // set color of a single bar, solid colored bar\n",
    "plot << new Bars(x: (1..5), y: [3, 5, 2, 3, 7], color: cs, outlineColor: Color.black, width: 0.3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot = new Plot(title: \"Changing Point Size, Color, Shape\")\n",
    "def y1 = [6, 7, 12, 11, 8, 14]\n",
    "def y2 = y1.collect { it - 2 }\n",
    "def y3 = y2.collect { it - 2 }\n",
    "def y4 = y3.collect { it - 2 }\n",
    "plot << new Points(y: y1)\n",
    "plot << new Points(y: y2, shape: ShapeType.CIRCLE)\n",
    "plot << new Points(y: y3, size: 8.0, shape: ShapeType.DIAMOND)\n",
    "plot << new Points(y: y4, size: 12.0, color: Color.orange, outlineColor: Color.red)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot = new Plot(title: \"Changing point properties with list\")\n",
    "def cs = [Color.black, Color.red, Color.orange, Color.green, Color.blue, Color.pink]\n",
    "def ss = [6.0, 9.0, 12.0, 15.0, 18.0, 21.0]\n",
    "def fs = [false, false, false, true, false, false]\n",
    "plot << [new Points(y: [5] * 6, size: 12.0, color: cs),\n",
    "         new Points(y: [4] * 6, size: 12.0, color: Color.gray, outlineColor: cs),\n",
    "         new Points(y: [3] * 6, size: ss, color: Color.red),\n",
    "         new Points(y: [2] * 6, size: 12.0, color: Color.black, fill: fs, outlineColor: Color.black)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Areas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot = new Plot()\n",
    "def y = [3, 5, 2, 3]\n",
    "def x0 = [0, 1, 2, 3]\n",
    "def x1 = [3, 4, 5, 8]\n",
    "plot << new Area(x: x0, y: y)\n",
    "plot << new Area(x: x1, y: y, color: new Color(128, 128, 128, 50), interpolation: 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def p = new Plot()\n",
    "p << new Line(y: [3, 6, 12, 24], displayName: \"Median\")\n",
    "p << new Area(y: [4, 8, 16, 32], base: [2, 4, 8, 16],\n",
    "              color: new Color(255, 0, 0, 50), displayName: \"Q1 to Q3\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# XYStacker"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def y1 = [1,5,3,2,3]\n",
    "def y2 = [7,2,4,1,3]\n",
    "def p = new Plot(title: 'Plot with XYStacker', initHeight: 200)\n",
    "def a1 = new Area(y: y1, displayName: 'y1')\n",
    "def a2 = new Area(y: y2, displayName: 'y2')\n",
    "p << XYStacker.stack([a1, a2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ConstantLines and ConstantBands"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def p = new Plot ()\n",
    "p << new Line(y: [-1, 1])\n",
    "p << new ConstantLine(x: 0.65, style: StrokeType.DOT, color: Color.blue)\n",
    "p << new ConstantLine(y: 0.1, style: StrokeType.DASHDOT, color: Color.blue)\n",
    "p << new ConstantLine(x: 0.3, y: 0.4, color: Color.gray, width: 5, showLabel: true)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "new Plot() << new Line(y: [-3, 1, 3, 4, 5]) << new ConstantBand(x: [1, 2], y: [1, 3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def p = new Plot() \n",
    "p << new Line(x: [-3, 1, 2, 4, 5], y: [4, 2, 6, 1, 5])\n",
    "p << new ConstantBand(x: [Double.NEGATIVE_INFINITY, 1], color: new Color(128, 128, 128, 50))\n",
    "p << new ConstantBand(x: [1, 2])\n",
    "p << new ConstantBand(x: [4, Double.POSITIVE_INFINITY])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Text"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot = new Plot()\n",
    "def xs = (1..10)\n",
    "def ys = [8.6, 6.1, 7.4, 2.5, 0.4, 0.0, 0.5, 1.7, 8.4, 1]\n",
    "def label = { i ->\n",
    "  if (ys[i] > ys[i+1] && ys[i] > ys[i-1]) return \"max\"\n",
    "  if (ys[i] < ys[i+1] && ys[i] < ys[i-1]) return \"min\"\n",
    "  if (ys[i] > ys[i-1]) return \"rising\"\n",
    "  if (ys[i] < ys[i-1]) return \"falling\"\n",
    "  return \"\"\n",
    "}\n",
    "for (i = 0; i < xs.size(); i++) {\n",
    "  if (i > 0 && i < xs.size()-1)\n",
    "    plot << new Text(x: xs[i], y: ys[i], text: label(i),  pointerAngle: -i/3.0)\n",
    "}\n",
    "plot << new Line(x: xs, y: ys)\n",
    "plot << new Points(x: xs, y: ys)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Crosshair"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def ch = new Crosshair(color: new Color(255, 128, 5), width: 2, style: StrokeType.DOT)\n",
    "pp = new Plot(crosshair: ch, omitCheckboxes: true,\n",
    "                  legendLayout: LegendLayout.HORIZONTAL, legendPosition: LegendPosition.TOP)\n",
    "def x = [1, 4, 6, 8, 10]\n",
    "def y = [3, 6, 4, 5, 9]\n",
    "pp << new Line(displayName: \"Line\", x: x, y: y, width: 3)\n",
    "pp << new Bars(displayName: \"Bar\", x: (1..10), y: [2, 2, 4, 4, 2, 2, 0, 2, 2, 4], width: 0.5)\n",
    "pp << new Points(x: x, y: y, size: 10, toolTip: {xs, ys -> \"x = \" + xs + \", y = \" + ys })"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pp.setLegendPosition(LegendPosition.RIGHT);\n",
    "OutputCell.HIDDEN"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SimpleTimePlot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import com.twosigma.beakerx.fileloader.CSV\n",
    "rates = new CSV().read(\"../../../doc/resources/data/interest-rates.csv\")\n",
    "def size = rates.size()\n",
    "(0 ..< size).each{row = rates[it]; row.spread = row.y10 - row.m3}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "new SimpleTimePlot(rates, [\"y1\", \"y10\"], // column names\n",
    "                   timeColumn : \"time\", // time is default value for a timeColumn\n",
    "                   yLabel: \"Price\", \n",
    "                   displayNames: [\"1 Year\", \"10 Year\"],\n",
    "                   colors : [[216, 154, 54], '#aabbcc'],\n",
    "                   displayLines: false, // no lines (true by default)\n",
    "                   displayPoints: true) // show points (false by default))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Second Y Axis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def p = new TimePlot(xLabel: \"Time\", yLabel: \"Interest Rates\")\n",
    "p << new YAxis(label: \"Spread\", upperMargin: 4)\n",
    "p << new Area(x: rates.time, y: rates.spread, displayName: \"Spread\",\n",
    "              yAxis: \"Spread\", color: new Color(180, 50, 50, 128))\n",
    "p << new Line(x: rates.time, y: rates.m3, displayName: \"3 Month\")\n",
    "p << new Line(x: rates.time, y: rates.y10, displayName: \"10 Year\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Date object for the time coordinate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cal = Calendar.getInstance();\n",
    "cal.add(Calendar.HOUR, -1)\n",
    "\n",
    "def today = new Date();\n",
    "def millis = today.time;\n",
    "def hour = 1000 * 60 * 60;\n",
    "\n",
    "def plot = new TimePlot(\n",
    "  timeZone: new SimpleTimeZone(10800000, \"America/New_York\")\n",
    ");\n",
    "//list of milliseconds\n",
    "plot << new Points(x:(0..10).collect{millis + hour * it}, y:(0..10), size: 10, displayName: \"milliseconds\");\n",
    "//list of java.util.Date objects\n",
    "plot << new Points(x:(0..10).collect{cal.add(Calendar.HOUR, 1); cal.getTime()}, y:(0..10), size: 4, displayName: \"date objects\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# NanoPlot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def today  = new Date()\n",
    "def millis = today.time\n",
    "def nanos  = millis * 1000 * 1000g // g makes it arbitrary precision\n",
    "def np = new NanoPlot()\n",
    "np << new Points(x:(0..10).collect{nanos + 7 * it}, y:(0..10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def points = 100;\n",
    "def logBase = 10;\n",
    "def expys = [];\n",
    "def xs = [];\n",
    "for(int i = 0; i < points; i++){\n",
    "  xs[i] = i / 15.0;\n",
    "  expys[i] = Math.exp(xs[i]); \n",
    "}\n",
    "\n",
    "def cplot = new CombinedPlot(xLabel: \"Linear\");\n",
    "def logYPlot = new Plot(title: \"Linear x, Log y\", yLabel: \"Log\", logY: true, yLogBase: logBase);\n",
    "logYPlot << new Line(x: xs, y: expys, displayName: \"f(x) = exp(x)\");\n",
    "logYPlot << new Line(x: xs, y: xs, displayName: \"g(x) = x\");\n",
    "cplot.add(logYPlot, 3);\n",
    "\n",
    "// works for 2nd Y axis too:\n",
    "// logYPlot << new YAxis(label: \"Right Log Y-Axis\", log: true, logBase: logBase);\n",
    "\n",
    "def linearYPlot = new Plot(title: \"Linear x, Linear y\", yLabel: \"Linear\");\n",
    "linearYPlot << new Line(x: xs, y: expys, displayName: \"f(x) = exp(x)\");\n",
    "linearYPlot << new Line(x: xs, y: xs, displayName: \"g(x) = x\");\n",
    "cplot.add(linearYPlot, 3);\n",
    "\n",
    "cplot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def points = 100;\n",
    "def logBase = 10;\n",
    "def expys = [];\n",
    "def xs = [];\n",
    "for(int i = 0; i < points; i++){\n",
    "  xs[i] = i /15\n",
    "  expys[i] = Math.exp(xs[i]);\n",
    "}\n",
    "\n",
    "def plot = new Plot(title: \"Log x, Log y\", xLabel: \"Log\", yLabel: \"Log\",\n",
    "                    logX: true, xLogBase: logBase, logY: true, yLogBase: logBase);\n",
    "\n",
    "plot << new Line(x: xs, y: expys, displayName: \"f(x) = exp(x)\");\n",
    "plot << new Line(x: xs, y: xs, displayName: \"f(x) = x\");\n",
    "\n",
    "plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = new Plot(title: \"No Tick Labels\", xTickLabelsVisible: false, yTickLabelsVisible: false)\n",
    "p << new Line([0, 1, 6, 5, 2, 8])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "r = new Random()\n",
    "p = new Plot(title: \"Advanced Plot Styling\",\n",
    "         labelStyle: \"font-size:32px; font-weight: bold; font-family: courier; fill: green;\",\n",
    "         gridLineStyle:  \"stroke: purple; stroke-width: 3;\",\n",
    "         titleStyle: \"color: green;\"\n",
    "        )\n",
    "p << new Points(x: (1..1000).collect { r.nextGaussian() * 10.0d },\n",
    "                y: (1..1000).collect { r.nextGaussian() * 20.0d })"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import java.nio.file.Files\n",
    "byte[] picture = Files.readAllBytes(new File(\"../../../doc/resources/img/widgetArch.png\").toPath());\n",
    "def p =  new Plot();\n",
    "// x y width height are coordinates, opacity is a double in 0~1\n",
    "\n",
    "// image can be loaded via bytes, filepath, or url\n",
    "p << new Rasters(x: [-10,3], y: [3,1.5], width: [6,5], height:[10,8], opacity: [1,0.5], dataString: picture);\n",
    "//p << new Rasters(x: -1, y: 4.5, width: 5, height: 8, opacity:0.5, filePath: \"widgetArch.png\");\n",
    "p << new Rasters(x: [-4], y: [10.5], width: [7], height: [2], opacity:[1], fileUrl: \"https://www.twosigma.com/static/img/twosigma.png\");\n",
    "\n",
    "// a list of images!\n",
    "def x = [-8, -5, -3, -2, -1, 1, 2, 4, 6, 8]\n",
    "def y = [4, 5, 1, 2, 0 ,3, 6, 4, 5, 9]\n",
    "def width = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n",
    "def opacity = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]\n",
    "p << new Rasters(x: x, y: y, width:width, height:width, opacity:opacity,fileUrl: \"http://icons.iconarchive.com/icons/paomedia/small-n-flat/1024/sign-check-icon.png\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot = new Plot(title: \"Setting 2nd Axis bounds\")\n",
    "def ys = [0, 2, 4, 6, 15, 10]\n",
    "def ys2 = [-40, 50, 6, 4, 2, 0]\n",
    "def ys3 = [3, 6, 3, 6, 70, 6]\n",
    "plot << new YAxis(label:\"Spread\")\n",
    "plot << new Line(y: ys)\n",
    "plot << new Line(y: ys2, yAxis: \"Spread\")\n",
    "plot.getYAxes()[0].setBound(1,5);\n",
    "plot.getYAxes()[1].setBound(3,6) // this should change the bounds of the 2nd, right axis\n",
    "plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "new Line(y: [4, 0], x: [0, 5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Groovy",
   "language": "groovy",
   "name": "groovy"
  },
  "language_info": {
   "codemirror_mode": "groovy",
   "file_extension": ".groovy",
   "mimetype": "",
   "name": "Groovy",
   "nbconverter_exporter": "",
   "version": "2.5.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
